package mixing

import (
	"net/http"
	"strconv"

	"gitee.com/wangshh_123/cross-pay-go/src/models"
	pcommon "gitee.com/wangshh_123/cross-pay-go/src/platform/common"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common/i18n"

	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// ExchangeLossRuleController 汇率损失规则控制器
// 提供查询和更新接口
// Author: AI
// Date: 2024-06-09

type ExchangeLossRuleController struct {
	service *service.ExchangeLossRuleService
	db      *gorm.DB
	config  *pcommon.PlatformConfig
}

// NewExchangeLossRuleController 创建控制器实例
func NewExchangeLossRuleController(db *gorm.DB, config *pcommon.PlatformConfig) *ExchangeLossRuleController {
	return &ExchangeLossRuleController{
		service: service.NewExchangeLossRuleService(db),
		db:      db,
		config:  config,
	}
}

// GetExchangeLossRule 查询用户专属或全局默认汇率损失规则
// GET /exchange-loss-rule?user_id=xxx
func (c *ExchangeLossRuleController) GetExchangeLossRule(ctx *gin.Context) {
	userIDStr := ctx.Query("user_id")
	var userID *int64
	if userIDStr != "" {
		id, err := strconv.ParseInt(userIDStr, 10, 64)
		if err != nil {
			common.Error(ctx, http.StatusBadRequest, "invalid_id", err)
			return
		}
		userID = &id
	}

	// 先查询用户特定规则
	rule, err := c.service.GetExchangeLossRule(ctx, userID)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			// 如果用户没有特定规则，查询默认规则
			rule, err = c.service.GetExchangeLossRule(ctx, nil)
			if err != nil {
				common.Error(ctx, http.StatusNotFound, "exchange_loss_rule_not_found", err)
				return
			}
		} else {
			common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_query_failed", err)
			return
		}
	}

	// 只返回 active 状态的规则
	if rule.Status != "active" {
		common.Error(ctx, http.StatusNotFound, "exchange_loss_rule_not_found", nil)
		return
	}

	common.Success(ctx, i18n.GetMessages("exchange_loss_rule_query_success"), rule)
}

// UpdateExchangeLossRule 更新汇率损失规则
// PUT /exchange-loss-rule
func (c *ExchangeLossRuleController) UpdateExchangeLossRule(ctx *gin.Context) {
	var req struct {
		UserID *int64  `json:"user_id"`
		Rate   float64 `json:"rate" binding:"required"`
		Status string  `json:"status"`
	}
	var err error // 提前声明err变量
	if err = ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 验证并转换rate为decimal
	rateDecimal := decimal.NewFromFloat(req.Rate)

	// 如果提供了 user_id，检查用户是否存在
	if req.UserID != nil {
		var user models.User
		if err = c.db.First(&user, req.UserID).Error; err != nil {
			common.Error(ctx, http.StatusBadRequest, "user_not_found", err)
			return
		}
	}

	// 设置默认状态
	if req.Status == "" {
		req.Status = "active"
	}

	// 查询规则是否存在
	var existingRule models.ExchangeLossRule
	query := c.db.Model(&models.ExchangeLossRule{})
	if req.UserID != nil {
		query = query.Where("user_id = ?", req.UserID)
	} else {
		query = query.Where("is_default = 1")
	}
	err = query.First(&existingRule).Error

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			// 规则不存在，创建新规则
			isDefault := 0
			if req.UserID == nil {
				isDefault = 1
			}
			newRule := &models.ExchangeLossRule{
				UserID:    req.UserID,
				Rate:      rateDecimal,
				IsDefault: isDefault,
				Status:    req.Status,
			}
			if err := c.service.CreateExchangeLossRule(ctx, newRule); err != nil {
				common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_create_failed", err)
				return
			}
			common.Success(ctx, i18n.GetMessages("exchange_loss_rule_create_success"), newRule)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_query_failed", err)
		}
		return
	}

	// 更新现有规则
	updates := map[string]interface{}{
		"rate":   rateDecimal,
		"status": req.Status,
	}
	if err := c.service.UpdateExchangeLossRule(ctx, existingRule.ID, updates); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_update_failed", err)
		return
	}

	common.Success(ctx, i18n.GetMessages("exchange_loss_rule_update_success"))
}

// DeleteExchangeLossRule 删除汇率损失规则（软删除）
// DELETE /exchange-loss-rule?user_id=xxx
func (c *ExchangeLossRuleController) DeleteExchangeLossRule(ctx *gin.Context) {
	userIDStr := ctx.Query("user_id")
	if userIDStr == "" {
		common.Error(ctx, http.StatusBadRequest, "user_id_required", nil)
		return
	}

	userID, err := strconv.ParseInt(userIDStr, 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_user_id", err)
		return
	}

	// 查找用户对应的规则
	var rule models.ExchangeLossRule
	if err := c.db.Where("user_id = ?", userID).First(&rule).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "exchange_loss_rule_not_found", nil)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_query_failed", err)
		}
		return
	}

	if rule.IsDefault == 1 {
		common.Error(ctx, http.StatusForbidden, "cannot_delete_default_rule", nil)
		return
	}

	// 软删除：将状态更新为 inactive
	updates := map[string]interface{}{
		"status": "inactive",
	}
	if err := c.service.UpdateExchangeLossRule(ctx, rule.ID, updates); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_delete_failed", err)
		return
	}

	common.Success(ctx, i18n.GetMessages("exchange_loss_rule_delete_success"))
}

// GetExchangeLossRuleList 获取汇损规则列表
// GET /exchange-loss-rules
func (c *ExchangeLossRuleController) GetExchangeLossRuleList(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))
	if page < 1 {
		page = 1
	}
	if pageSize < 1 {
		pageSize = 10
	}

	// 获取筛选参数
	userName := ctx.Query("user_name")
	userEmail := ctx.Query("user_email")
	userPhone := ctx.Query("user_phone")

	// 构建查询条件
	query := c.db.Model(&models.ExchangeLossRule{}).
		Where("exchange_loss_rules.status = ?", "active")

	// 如果有用户信息筛选条件，需要关联用户表
	if userName != "" || userEmail != "" || userPhone != "" {
		query = query.Joins("LEFT JOIN users ON users.id = exchange_loss_rules.user_id")

		if userName != "" {
			query = query.Where("users.name LIKE ?", "%"+userName+"%")
		}
		if userEmail != "" {
			query = query.Where("users.email LIKE ?", "%"+userEmail+"%")
		}
		if userPhone != "" {
			query = query.Where("users.phone LIKE ?", "%"+userPhone+"%")
		}
	}

	// 获取总数
	var total int64
	if err := query.Count(&total).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_count_failed", err)
		return
	}

	// 获取分页数据
	var rules []models.ExchangeLossRule
	if err := query.
		Select("exchange_loss_rules.*").
		Offset((page - 1) * pageSize).
		Limit(pageSize).
		Order("exchange_loss_rules.is_default DESC, exchange_loss_rules.created_at DESC").
		Find(&rules).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_query_failed", err)
		return
	}

	// 收集需要查询的用户ID
	var userIDs []int64
	for _, rule := range rules {
		if rule.UserID != nil {
			userIDs = append(userIDs, *rule.UserID)
		}
	}

	// 查询用户信息
	type UserInfo struct {
		ID    int64  `gorm:"column:id"`
		Name  string `gorm:"column:name"`
		Email string `gorm:"column:email"`
		Phone string `gorm:"column:phone"`
	}
	var users []UserInfo
	if len(userIDs) > 0 {
		if err := c.db.Table("users").
			Select("id, name, email, phone").
			Where("id IN ?", userIDs).
			Find(&users).Error; err != nil {
			common.Error(ctx, http.StatusInternalServerError, "get_users_failed", err)
			return
		}
	}

	// 构建用户ID到用户信息的映射
	userMap := make(map[int64]UserInfo)
	for _, user := range users {
		userMap[user.ID] = user
	}

	// 构建响应数据
	type RuleWithUser struct {
		models.ExchangeLossRule
		User *UserInfo `json:"user,omitempty"`
	}

	var rulesWithUser []RuleWithUser
	for _, rule := range rules {
		ruleWithUser := RuleWithUser{
			ExchangeLossRule: rule,
		}
		if rule.UserID != nil {
			if user, exists := userMap[*rule.UserID]; exists {
				ruleWithUser.User = &user
			}
		}
		rulesWithUser = append(rulesWithUser, ruleWithUser)
	}
	// 构建响应数据
	response := map[string]interface{}{
		"total":     total,
		"page":      page,
		"page_size": pageSize,
		"list":      rulesWithUser,
	}

	common.Success(ctx, i18n.GetMessages("exchange_loss_rule_list_success"), response)
}

// GetUserExchangeLossRule 获取当前用户的汇损规则
// GET /user/exchange-loss-rule
func (c *ExchangeLossRuleController) GetUserExchangeLossRule(ctx *gin.Context) {
	// 获取当前用户ID
	userID, exists := ctx.Get("user_id")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "UNAUTHORIZED", nil)
		return
	}

	// 将 userID 转换为 int64
	userIDInt64, ok := userID.(int64)
	if !ok {
		common.Error(ctx, http.StatusBadRequest, "invalid_user_id", nil)
		return
	}

	// 先查询用户特定规则
	rule, err := c.service.GetExchangeLossRule(ctx, &userIDInt64)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			// 如果用户没有特定规则，查询默认规则
			rule, err = c.service.GetExchangeLossRule(ctx, nil)
			if err != nil {
				common.Error(ctx, http.StatusNotFound, "exchange_loss_rule_not_found", err)
				return
			}
		} else {
			common.Error(ctx, http.StatusInternalServerError, "exchange_loss_rule_query_failed", err)
			return
		}
	}

	// 只返回 active 状态的规则
	if rule.Status != "active" {
		common.Error(ctx, http.StatusNotFound, "exchange_loss_rule_not_found", nil)
		return
	}

	common.Success(ctx, i18n.GetMessages("exchange_loss_rule_query_success"), rule)
}
